#ifndef TCP_TCPCONNECTION_H
#define TCP_TCPCONNECTION_H

#include <memory>
#include <functional>
#include <boost/any.hpp>

#include "Buffer.h"
#include "reactor/Callback.h"
#include "tcp/InetAddress.h"
#include "tcp/Socket.h"
#include "tcp/Channel.h"
#include "reactor/EventLoop.h"


class TcpConnection : public std::enable_shared_from_this<TcpConnection> {
public:
    TcpConnection(EventLoop *loop,
                  std::string name,
                  int sockfd,
                  const InetAddress &localAddr,
                  const InetAddress &peerAddr);

    ~TcpConnection();

    EventLoop *getLoop() const { return loop_; }

    const string &getName() const { return name_; }

    /**
     * 获取 TcpServer 的地址
     */
    const InetAddress &localAddress() const { return localAddr_; }

    /**
     * 获取客户端连接的地址
     */
    const InetAddress &peerAddress() const { return peerAddr_; }

    /**
     * 是否已连接
     */
    bool connected() const { return state_ == kConnected; }

    /**
     * 连接是否已关闭
     */
    bool disConnected() const { return state_ == kDisconnected; }

    bool getTcpInfo(struct tcp_info *) const;

    /* 各种发送方式 */
    void send(const void *message, size_t len);

    void send(const std::string &message);

    void send(Buffer *message);

    /* 用于关闭连接的写入端用的 */
    void shutdown();
    // FIXME: 注意这个非线程安全

    /**
     * 设置Tcp No Delay选项的开启
     */
    void setTcpNoDelay(bool on);

    /* 设置对应回调函数 */
    void
    setConnectionCallback(const ConnectionCallback &connectionCallback) { connectionCallback_ = connectionCallback; }

    void setMessageCallback(const MessageCallback &messageCallback) { messageCallback_ = messageCallback; }

    void setCloseCallback(const CloseCallback &closeCallback) { closeCallback_ = closeCallback; }

    void setWriteCompleteCallback(const WriteCompleteCallback &cb) { writeCompleteCallback_ = cb; }

    void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t highWaterMark) {
        highWaterMarkCallback_ = cb;
        highWaterMark_ = highWaterMark;
    }

    void setContext(const boost::any &context) { context_ = context; }

    const boost::any &getContext() const { return context_; }

    boost::any *getMutableContext() { return &context_; }

    /* 连接的建立和销毁对应处理 */
    void connectionEstablished();

    void connectDestroyed();

private:
    enum StateE {
        kConnecting,
        // 连接中
        kConnected,
        // 已连接
        kDisconnected,
        // 连接已经销毁
        kDisconnecting
        // 连接销毁中
    };

    /* 各种事件的处理 */
    void handleRead(Timestamp receiveTime);

    void handleWrite();

    void handleClose();

    void handleError();

    /* 在对应事件循环中发送对应的消息 */
    void sendInLoop(const std::string &message);

    void sendInLoop(const void *message, size_t len);

    void shutdownInLoop();

    void setState(StateE s) { state_ = s; }

private:
    EventLoop *loop_;
    std::string name_;
    // 连接名称
    StateE state_;
    // 当前连接状态
    bool reading_;

    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    const InetAddress localAddr_;
    // 这个是本地Server的地址信息, peer才是远程连接的地址信息
    const InetAddress peerAddr_;

    /* 各种事件的回调函数 */
    ConnectionCallback connectionCallback_;
    MessageCallback messageCallback_;
    CloseCallback closeCallback_;
    WriteCompleteCallback writeCompleteCallback_;
    HighWaterMarkCallback highWaterMarkCallback_;

    size_t highWaterMark_;
    Buffer inputBuffer_;
    Buffer outputBuffer_;
    // 发送的数据如果无法一次发送完毕就先存储到发送缓冲区等待下一次可写事件通知
    boost::any context_;
};

#endif //TCP_TCPCONNECTION_H
